home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1990-1992 by Michael Davidson.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation.
- *
- * This software is provided "as is" without express or implied warranty.
- */
-
- /*
- * tseng.c - support routines for Tseng Labs ET3000 and ET4000 chipsets
- */
-
- #include "vdev.h"
- #include "svga.h"
-
- #define ET3000 0x01 /* ET3000 chipset */
- #define ET4000 0x02 /* ET4000 chipset */
-
- #define M_256K 0x10
- #define M_512K 0x20
- #define M_1024K 0x40
-
- #define GRAPHICS (SVGA_MODE_SUPPORTED | SVGA_GRAPHICS_MODE)
- #define TEXT (SVGA_MODE_SUPPORTED | SVGA_TEXT_MODE)
-
- static struct svga_mode_info tseng_modes[] =
- {
- { 1024, 768, 8, 0x38, GRAPHICS },
- { 800, 600, 8, 0x30, GRAPHICS },
- { 640, 480, 8, 0x2e, GRAPHICS },
- { 320, 200, 8, 0x13, GRAPHICS },
- { 80, 25, 0, 0x03, TEXT },
- { 0, 0, 0, 0x00, 0 }
- };
-
- static void tseng3_bank_switch();
- static void tseng4_bank_switch();
- static int tseng_present();
-
- /*ARGSUSED*/
- int
- tseng_init(
- char *name,
- struct vdev *v
- )
- {
- int r;
- void (*tseng_bank_switch)();
-
- if (! (r = tseng_present()))
- return -1;
-
-
- if (r == ET4000)
- {
- v->v_name = "Tseng Labs ET4000 chipset";
- tseng_bank_switch = tseng4_bank_switch;
- }
- else
- {
- v->v_name = "Tseng Labs ET3000 chipset";
- tseng_bank_switch = tseng3_bank_switch;
- tseng_modes[0].attributes &= ~SVGA_MODE_SUPPORTED;
- }
-
- svga_setup(v, tseng_modes, tseng_bank_switch);
-
- return 0;
- }
-
- int
- tseng_probe()
- {
- return tseng_present();
- }
-
- /*
- * tseng_present() - check for presence or ET3000 or ET4000
- */
- static int
- tseng_present()
- {
- int base;
- int old;
- int new;
-
- outb(0x3bf, 0x03);
- base = (inb(0x3cc) & 0x01) ? 0x3d0 : 0x3b0;
-
- outb(base + 8, 0xa0);
-
- inb(0x3da);
- outb(0x3c0, 0x16);
- old = inb(0x3c1);
-
- inb(0x3da);
- outb(0x3c0, 0x16);
- outb(0x3c0, old ^ 0x10);
-
- inb(0x3da);
- outb(0x3c0, 0x16);
- new = inb(0x3c1);
-
- inb(0x3da);
- outb(0x3c0, 0x16);
- outb(0x3c0, old);
-
- if (new != (old ^ 0x10))
- return 0;
-
- outb(base+4, 0x33);
- old = inb(base+5);
- outb(base+5, old ^ 0x0f);
- new = inb(base+5);
- outb(base+5, old);
-
- if (new == (old ^ 0x0f))
- return ET4000;
- else
- return ET3000;
- }
-
- /*
- * tseng3_bank_switch()
- */
- static void
- tseng3_bank_switch(
- int x
- )
- {
- x &= 7;
- x |= (x << 3);
-
- outb(0x3cd, x | 0x40);
- }
-
- /*
- * tseng4_bank_switch()
- */
- static void
- tseng4_bank_switch(
- int x
- )
- {
- x &= 0xf;
- x |= (x << 4);
-
- outb(0x3bf, 0x03);
- outb(0x3d8, 0xa0);
-
- outb(0x3cd, x);
- }
-